using System;
using System.Collections.Generic;
using NUnit.Framework;
using ValidationFramework.Reflection;

namespace ValidationFramework.Tests
{
    public class RequiredBoolRuleTest
    {

        const string expectedErrorMessage = "expectedErrorMessage";
        const string expectedRuleSet = "EXPECTEDRULESET";

        [TestFixture]
        public class Construction
        {

            [Test]
            public void Simple1()
            {
                var rule = new RequiredBoolRule(expectedErrorMessage, false);
                Assert.AreEqual(expectedErrorMessage, rule.ErrorMessage);
                Assert.IsFalse(rule.UseErrorMessageProvider);

            }


            [Test]
            public void Simple2()
            {
                var rule = new RequiredBoolRule(expectedErrorMessage);
                Assert.AreEqual(expectedErrorMessage, rule.ErrorMessage);
                Assert.IsFalse(rule.UseErrorMessageProvider);

            }


            [Test]
            public void Simple3()
            {
                var rule = new RequiredBoolRule();
                Assert.IsNull(rule.ErrorMessage);
                Assert.IsFalse(rule.UseErrorMessageProvider);

            }
        }
        [TestFixture]
        public class RuleInterpretation
        {

            [Test]
            public void Simple()
            {
                var rule = new RequiredBoolRule(null, false);
                 rule.CheckType(new MockInfoDescriptor(typeof(bool).TypeHandle, "foo"));
                Assert.IsNotNull(rule.RuleInterpretation);
            }
        }

        [TestFixture]
        public class IsEquivalent
        {
            [Test]
            public void Simple()
            {
                var rule1 = new RequiredBoolRule(null, false);
                var rule2 = new RequiredBoolRule(null, false);
                Assert.IsTrue(rule1.IsEquivalent(rule2));
                rule2 = new RequiredBoolRule("foo", false);
                Assert.IsTrue(rule1.IsEquivalent(rule2));

            }
        }
        [TestFixture]
        public class Validate
        {
            [Test]
            public void Simple()
            {

                var nullableRule = new RequiredBoolRule(null, false);
                Assert.IsNotNull(nullableRule.Validate(null, null, null, null));
                Assert.IsNull(nullableRule.Validate(null, false, null, null));
                Assert.IsNull(nullableRule.Validate(null, true, null, null));

            }
        }
        [TestFixture]
        public class CheckTypes
        {

            [Test]
            public void Simple()
            {
                var rule = new RequiredBoolRule(null, false);
                                   rule.CheckType(new MockInfoDescriptor(typeof (bool).TypeHandle, "foo"));
            }

            [Test]
            [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Member 'foo' must be a 'System.Boolean' to be used for the ValidationFramework.RequiredBoolRule. Actual Type 'System.Object'.\r\nParameter name: value")]
            public void ExceptionInvalidType1()
            {
                var rule = new RequiredBoolRule(null, false);
                rule.CheckType(new MockInfoDescriptor(typeof (object).TypeHandle, "foo"));
            }

            [Test]
            [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Member 'foo' must be a 'System.Boolean' to be used for the ValidationFramework.RequiredBoolRule. Actual Type 'System.Int32'.\r\nParameter name: value")]
            public void ExceptionInvalidType2()
            {
                var rule = new RequiredBoolRule(null, false);
                                   rule.CheckType(new MockInfoDescriptor(TypePointers.IntTypeHandle, "foo"));
            }

            [Test]
            [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Member 'foo' must be a 'System.Boolean' to be used for the ValidationFramework.RequiredBoolRule. Actual Type 'System.Collections.Generic.List<T>'.\r\nParameter name: value")]
            public void ExceptionInvalidType3()
            {
                var rule = new RequiredBoolRule(null, false);
                rule.CheckType(new MockInfoDescriptor(typeof (List<>).TypeHandle, "foo"));
            }
        }


    }
}